package com.ourteam.product.requirement.api;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ourteam.frame.controller.AbstractServiceController;
import com.ourteam.frame.web.AbstractSearchHelper;
import com.ourteam.frame.web.GridBean;
import com.ourteam.frame.web.OperationResult;
import com.ourteam.frame.web.TreeViewNodeBean;
import com.ourteam.product.requirement.dao.IProductCatalogDAO;
import com.ourteam.product.requirement.dao.IProductRequirementDAO;
import com.ourteam.product.requirement.dao.IProductVersionDAO;
import com.ourteam.product.requirement.dao.ProductCatalogDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductDefineDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductFeatureCheckListDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductGlossaryAttrDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductGlossaryDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductGlossaryRelateDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductRequirementDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductRequirementFeatureRelateDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductRoleDefineDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductRoleRelateDAOFactory;
import com.ourteam.product.requirement.dao.ProductRoleRelateDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductTeamDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductVersionDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductVersionRelateDAOFactory;
import com.ourteam.product.requirement.dao.ProductVersionRelateDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductVersionStageDAOQueryBean;
import com.ourteam.product.requirement.domain.ProductCatalogBean;
import com.ourteam.product.requirement.domain.ProductDefineBean;
import com.ourteam.product.requirement.domain.ProductElementTypeEnum;
import com.ourteam.product.requirement.domain.ProductFeatureBean;
import com.ourteam.product.requirement.domain.ProductFeatureCheckListBean;
import com.ourteam.product.requirement.domain.ProductGlossaryAttrBean;
import com.ourteam.product.requirement.domain.ProductGlossaryBean;
import com.ourteam.product.requirement.domain.ProductGlossaryRelateBean;
import com.ourteam.product.requirement.domain.ProductRequirementBean;
import com.ourteam.product.requirement.domain.ProductRequirementFeatureRelateBean;
import com.ourteam.product.requirement.domain.ProductRoleDefineBean;
import com.ourteam.product.requirement.domain.ProductRoleRelateBean;
import com.ourteam.product.requirement.domain.ProductTeamBean;
import com.ourteam.product.requirement.domain.ProductVersionBean;
import com.ourteam.product.requirement.service.IProductCatalogService;
import com.ourteam.product.requirement.service.IProductService;
import com.ourteam.product.requirement.service.IProductVersionService;
import com.ourteam.product.requirement.service.ProductCatalogServiceFactory;
import com.ourteam.product.requirement.service.ProductServiceFactory;
import com.ourteam.product.requirement.service.ProductVersionServiceFactory;

@Controller
@RequestMapping("/api/PRODUCT/REQ/ProductDefine")
public class ProductDefineAPI extends AbstractServiceController {

	private static final IProductCatalogService PRODUCT_CATALOG_SERVICE = ProductCatalogServiceFactory
			.getProductCatalogService();

	private static final IProductService PRODUCT_DEFINE_SERVICE = ProductServiceFactory.getProductService();

	private static final IProductVersionService PRODUCT_VERSION_SERVICE = ProductVersionServiceFactory
			.getProductVersionService();

	@RequestMapping("/getProductCatalogById")
	@ResponseBody
	public ProductCatalogBean getProductCatalogById(@RequestParam long id) throws Exception {

		return PRODUCT_CATALOG_SERVICE.getProductCatalogById(id);
	}

	@RequestMapping("/saveProductCatalog")
	@ResponseBody
	public ProductCatalogBean saveProductCatalog(@ModelAttribute ProductCatalogBean productCatalogBean,
			HttpServletRequest request, Model model) throws Exception {

		long submitterId = getSubmitterId(request);

		if (productCatalogBean.getId() != 0) {
			PRODUCT_CATALOG_SERVICE.modifyProductCatalog(productCatalogBean);
		} else {
			PRODUCT_CATALOG_SERVICE.createProductCatalog(productCatalogBean);
		}

		return productCatalogBean;
	}

	@RequestMapping("/deleteProductCatalog")
	@ResponseBody
	public boolean deleteProductCatalog(long id) throws Exception {

		ProductDefineDAOQueryBean productDefineDAOQueryBean = new ProductDefineDAOQueryBean();

		productDefineDAOQueryBean.createCriteria().andCatalogIdEqualTo(id);

		int subProductDefineCount = PRODUCT_DEFINE_SERVICE.queryProductDefineCount(productDefineDAOQueryBean);

		ProductCatalogDAOQueryBean catalogDAOQueryBean = new ProductCatalogDAOQueryBean();

		catalogDAOQueryBean.createCriteria().andParentIdEqualTo(id);

		int subProductCatalogCount = PRODUCT_CATALOG_SERVICE.queryProductCatalogCount(catalogDAOQueryBean);

		if (subProductDefineCount > 0 || subProductCatalogCount > 0) {
			return false;
		} else {

			PRODUCT_CATALOG_SERVICE.deleteProductCatalog(id);

			return true;
		}

	}

	@RequestMapping("/getProductVersionTreeSelect")
	@ResponseBody
	public TreeViewNodeBean[] getProductVersionTreeSelect() throws Exception {

		List<TreeViewNodeBean> treeNodeBeans = new ArrayList<TreeViewNodeBean>();

		ProductDefineDAOQueryBean queryBean = new ProductDefineDAOQueryBean();

		// queryBean.createCriteria().andParentIdEqualTo(0);

		// queryBean.setSortProperty(IProductCatalogDAO.SortIndex);

		ProductDefineBean[] products = PRODUCT_DEFINE_SERVICE.queryProductDefines(queryBean);

		for (int i = 0; i < products.length; i++) {

			ProductDefineBean productDefine = products[i];

			TreeViewNodeBean nodeBean = new TreeViewNodeBean();

			nodeBean.setNodeData(productDefine);

			nodeBean.setId(String.valueOf(productDefine.getId()));

			nodeBean.setText(productDefine.getName());

			getProductVersions(productDefine.getId(), nodeBean);

			treeNodeBeans.add(nodeBean);
		}

		return treeNodeBeans.toArray(new TreeViewNodeBean[treeNodeBeans.size()]);
	}

	protected void getProductVersions(long parentId, TreeViewNodeBean treeNodeBean) throws Exception {

		ProductVersionDAOQueryBean queryBean = new ProductVersionDAOQueryBean();

		queryBean.createCriteria().andProductDefineIdEqualTo(parentId);

		queryBean.setSortProperty(IProductVersionDAO.SortIndex);

		ProductVersionBean[] versions = PRODUCT_VERSION_SERVICE.queryProductVersions(queryBean);

		List<TreeViewNodeBean> children = new ArrayList<>();

		for (int i = 0; i < versions.length; i++) {

			ProductVersionBean productVersion = versions[i];

			TreeViewNodeBean nodeBean = new TreeViewNodeBean();

			nodeBean.setNodeData(productVersion);

			nodeBean.setId(String.valueOf(productVersion.getId()));

			nodeBean.setText(productVersion.getProductVersion());

			children.add(nodeBean);
		}

		treeNodeBean.setNodes(children.toArray(new TreeViewNodeBean[children.size()]));

	}

	@RequestMapping("/getProductCatalogTreeSelect")
	@ResponseBody
	public TreeViewNodeBean[] getProductCatalogTreeSelect() throws Exception {

		List<TreeViewNodeBean> catalogBeans = new ArrayList<TreeViewNodeBean>();

		ProductCatalogDAOQueryBean queryBean = new ProductCatalogDAOQueryBean();

		queryBean.createCriteria().andParentIdEqualTo(0);

		queryBean.setSortProperty(IProductCatalogDAO.SortIndex);

		ProductCatalogBean[] catalogs = PRODUCT_CATALOG_SERVICE.queryProductCatalogs(queryBean);

		for (int i = 0; i < catalogs.length; i++) {

			ProductCatalogBean productCatalog = catalogs[i];

			TreeViewNodeBean nodeBean = new TreeViewNodeBean();

			nodeBean.setNodeData(productCatalog);

			nodeBean.setId(String.valueOf(productCatalog.getId()));

			nodeBean.setText(productCatalog.getName());

			getProductCatalogs(productCatalog.getId(), nodeBean);

			catalogBeans.add(nodeBean);
		}

		return catalogBeans.toArray(new TreeViewNodeBean[catalogBeans.size()]);
	}

	protected void getProductCatalogs(long parentId, TreeViewNodeBean catalogBean) throws Exception {

		ProductCatalogDAOQueryBean queryBean = new ProductCatalogDAOQueryBean();

		queryBean.createCriteria().andParentIdEqualTo(parentId);

		queryBean.setSortProperty(IProductCatalogDAO.SortIndex);

		ProductCatalogBean[] catalogs = PRODUCT_CATALOG_SERVICE.queryProductCatalogs(queryBean);

		List<TreeViewNodeBean> children = new ArrayList<>();

		for (int i = 0; i < catalogs.length; i++) {

			ProductCatalogBean productCatalog = catalogs[i];

			TreeViewNodeBean nodeBean = new TreeViewNodeBean();

			nodeBean.setNodeData(productCatalog);

			nodeBean.setId(String.valueOf(productCatalog.getId()));

			nodeBean.setText(productCatalog.getName());

			getProductCatalogs(productCatalog.getId(), nodeBean);

			children.add(nodeBean);
		}

		catalogBean.setNodes(children.toArray(new TreeViewNodeBean[children.size()]));

	}

	@RequestMapping("/saveProductDefine")
	@ResponseBody
	public ProductDefineBean saveProductDefine(@ModelAttribute ProductDefineBean productDefineBean) throws Exception {

		if (productDefineBean.getId() == 0) {
			PRODUCT_DEFINE_SERVICE.createProductDefine(productDefineBean);
		} else {
			PRODUCT_DEFINE_SERVICE.modifyProductDefine(productDefineBean);
		}

		return productDefineBean;

	}

	@RequestMapping("/deleteProductDefine")
	@ResponseBody
	public OperationResult deleteProductDefine(@RequestParam long id) throws Exception {

		PRODUCT_DEFINE_SERVICE.deleteProductDefine(id);

		return OperationResult.SUCCESS_RESULT;

	}

	@RequestMapping("/batchDeleteProductDefines")
	@ResponseBody
	public OperationResult batchDeleteProductDefines(@RequestParam long[] ids) throws Exception {

		if (ArrayUtils.isEmpty(ids)) {
			return OperationResult.SUCCESS_RESULT;
		}

		for (int i = 0; i < ids.length; i++) {
			PRODUCT_DEFINE_SERVICE.deleteProductDefine(ids[i]);
		}

		return OperationResult.SUCCESS_RESULT;

	}

	@RequestMapping("/getProductDefineById")
	@ResponseBody
	public ProductDefineBean getProductDefineById(@RequestParam long id) throws Exception {
		return PRODUCT_DEFINE_SERVICE.getProductDefineById(id);
	}

	@RequestMapping("/queryProductDefines")
	@ResponseBody
	public GridBean queryProductDefines(@ModelAttribute ProductDefineSearchModel searchModel,
			HttpServletRequest request, Model model) throws Exception {

		AbstractSearchHelper<ProductDefineDAOQueryBean, ProductDefineSearchModel> searchHelper = new AbstractSearchHelper<ProductDefineDAOQueryBean, ProductDefineSearchModel>(
				searchModel) {

			@Override
			protected int queryCount(ProductDefineDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductDefineCount(queryBean);
			}

			@Override
			protected Object[] queryData(ProductDefineDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductDefines(queryBean);
			}

			@Override
			protected ProductDefineDAOQueryBean createQueryBean() {
				return new ProductDefineDAOQueryBean();
			}

		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/saveProductVersion")
	@ResponseBody
	public ProductVersionBean saveProductVersion(@ModelAttribute ProductVersionBean productVersionBean)
			throws Exception {

		if (productVersionBean.getId() == 0) {
			PRODUCT_VERSION_SERVICE.addNewProductVersion(productVersionBean.getProductDefineId(),
					productVersionBean.getParentVersionId(), productVersionBean);
		} else {
			PRODUCT_VERSION_SERVICE.modifyProductVersion(productVersionBean);
		}

		return productVersionBean;

	}

	@RequestMapping("/getProductVersionById")
	@ResponseBody
	public ProductVersionBean getProductVersionById(@RequestParam long id) throws Exception {
		return PRODUCT_VERSION_SERVICE.getProductVersionById(id);
	}

	@RequestMapping("/getProductVersions")
	@ResponseBody
	public ProductVersionBean[] getProductVersions(@RequestParam long productDefineId) throws Exception {
		return PRODUCT_VERSION_SERVICE.getProductVersions(productDefineId, 0);
	}

	@RequestMapping("/queryProductVersionStages")
	@ResponseBody
	public GridBean queryProductVersionStages(@ModelAttribute ProductVersionStageSearchModel searchModel,
			HttpServletRequest request, Model model) throws Exception {

		AbstractSearchHelper<ProductVersionStageDAOQueryBean, ProductVersionStageSearchModel> searchHelper = new AbstractSearchHelper<ProductVersionStageDAOQueryBean, ProductVersionStageSearchModel>(
				searchModel) {

			@Override
			protected int queryCount(ProductVersionStageDAOQueryBean queryBean) throws Exception {
				return PRODUCT_VERSION_SERVICE.queryProductVersionStageCount(queryBean);
			}

			@Override
			protected Object[] queryData(ProductVersionStageDAOQueryBean queryBean) throws Exception {
				return PRODUCT_VERSION_SERVICE.queryProductVersionStages(queryBean);
			}

			@Override
			protected ProductVersionStageDAOQueryBean createQueryBean() {
				return new ProductVersionStageDAOQueryBean();
			}

		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/queryProductVersions")
	@ResponseBody
	public GridBean queryProductVersions(@ModelAttribute ProductVersionSearchModel searchModel,
			HttpServletRequest request, Model model) throws Exception {

		AbstractSearchHelper<ProductVersionDAOQueryBean, ProductVersionSearchModel> searchHelper = new AbstractSearchHelper<ProductVersionDAOQueryBean, ProductVersionSearchModel>(
				searchModel) {

			@Override
			protected int queryCount(ProductVersionDAOQueryBean queryBean) throws Exception {
				return PRODUCT_VERSION_SERVICE.queryProductVersionCount(queryBean);
			}

			@Override
			protected Object[] queryData(ProductVersionDAOQueryBean queryBean) throws Exception {
				return PRODUCT_VERSION_SERVICE.queryProductVersions(queryBean);
			}

			@Override
			protected ProductVersionDAOQueryBean createQueryBean() {
				return new ProductVersionDAOQueryBean();
			}

		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/deleteProductVerions")
	@ResponseBody
	public OperationResult deleteProductVerions(@RequestParam(value = "ids") long[] ids) throws Exception {

		for (int i = 0; i < ids.length; i++) {
			PRODUCT_VERSION_SERVICE.removeProductVersion(ids[i]);
		}

		return OperationResult.SUCCESS_RESULT;

	}

	@RequestMapping("/queryProductGlossary")
	@ResponseBody
	public GridBean queryProductGlossary(@ModelAttribute ProductGlossarySearchModel searchModel,
			HttpServletRequest request, Model model) throws Exception {

		AbstractSearchHelper<ProductGlossaryDAOQueryBean, ProductGlossarySearchModel> searchHelper = new AbstractSearchHelper<ProductGlossaryDAOQueryBean, ProductGlossarySearchModel>(
				searchModel) {

			@Override
			protected int queryCount(ProductGlossaryDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductGlossaryCount(queryBean);
			}

			@Override
			protected Object[] queryData(ProductGlossaryDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductGlossary(queryBean);
			}

			@Override
			protected ProductGlossaryDAOQueryBean createQueryBean() {
				return new ProductGlossaryDAOQueryBean();
			}

		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/deleteProductGlossary")
	@ResponseBody
	public OperationResult deleteProductGlossary(@RequestParam(value = "ids") long[] ids) throws Exception {

		PRODUCT_DEFINE_SERVICE.deleteProductGlossaries(ids);

		return OperationResult.SUCCESS_RESULT;

	}

	@RequestMapping("/saveProductGlossary")
	@ResponseBody
	public OperationResult saveProductGlossary(@RequestParam long productVersionId,
			@ModelAttribute ProductGlossaryBean productGlossaryBean) throws Exception {

		if (productGlossaryBean.getId() == 0) {
			PRODUCT_DEFINE_SERVICE.addProductGlossary(productVersionId, productGlossaryBean);
		} else {
			PRODUCT_DEFINE_SERVICE.modifyProductGlossary(productGlossaryBean);
		}

		OperationResult operationResult = new OperationResult(false, "", productGlossaryBean);

		return operationResult;

	}

	@RequestMapping("/getProductGlossaryById")
	@ResponseBody
	public ProductGlossaryBean getProductGlossaryById(@RequestParam long id) throws Exception {

		return PRODUCT_DEFINE_SERVICE.getProductGlossaryById(id);

	}

	@RequestMapping("/deleteProductFeatures")
	@ResponseBody
	public OperationResult deleteProductFeatures(@RequestParam(value = "ids") long[] ids) throws Exception {

		PRODUCT_DEFINE_SERVICE.deleteProductFeatures(ids);

		return OperationResult.SUCCESS_RESULT;

	}

	@RequestMapping("/deleteProductFeature")
	@ResponseBody
	public OperationResult deleteProductFeature(@RequestParam long id) throws Exception {

		PRODUCT_DEFINE_SERVICE.deleteProductFeatures(new long[] { id });

		return OperationResult.SUCCESS_RESULT;

	}

	@RequestMapping("/saveProductFeature/{productVersionId}")
	@ResponseBody
	public ProductFeatureBean saveProductFeature(@PathVariable long productVersionId,
			@ModelAttribute ProductFeatureBean productFeatureBean) throws Exception {

		if (productFeatureBean.getId() == 0) {
			PRODUCT_DEFINE_SERVICE.addNewProductFeature(productVersionId, productFeatureBean);
		} else {
			PRODUCT_DEFINE_SERVICE.modifyProductFeature(productFeatureBean);
		}

		return productFeatureBean;

	}

	@RequestMapping("/getProductFeatureById")
	@ResponseBody
	public ProductFeatureBean getProductFeatureById(@RequestParam long id) throws Exception {

		return PRODUCT_DEFINE_SERVICE.getProductFeatureById(id);
	}

	@RequestMapping("/queryProductFeatureCheckList")
	@ResponseBody
	public GridBean queryProductFeatureCheckList(@ModelAttribute ProductFeatureCheckListSearchModel searchModel,
			HttpServletRequest request, Model model) throws Exception {

		AbstractSearchHelper<ProductFeatureCheckListDAOQueryBean, ProductFeatureCheckListSearchModel> searchHelper = new AbstractSearchHelper<ProductFeatureCheckListDAOQueryBean, ProductFeatureCheckListSearchModel>(
				searchModel) {

			@Override
			protected int queryCount(ProductFeatureCheckListDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductFeatureCheckListCount(queryBean);
			}

			@Override
			protected Object[] queryData(ProductFeatureCheckListDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductFeatureCheckList(queryBean);
			}

			@Override
			protected ProductFeatureCheckListDAOQueryBean createQueryBean() {
				return new ProductFeatureCheckListDAOQueryBean();
			}

		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/getProductRequirementById")
	@ResponseBody
	public ProductRequirementBean getProductRequirementById(@RequestParam long id) throws Exception {

		return PRODUCT_DEFINE_SERVICE.getProductRequirementById(id);
	}

	@RequestMapping("/saveProductRequirement/{productVersionId}")
	@ResponseBody
	public ProductRequirementBean saveProductRequirement(@PathVariable long productVersionId,
			@ModelAttribute ProductRequirementBean productRequirementBean) throws Exception {

		if (productRequirementBean.getId() == 0) {
			productRequirementBean.setCreatorId(getLoginUserId());
			PRODUCT_DEFINE_SERVICE.addNewProductRequirement(productVersionId, productRequirementBean);
		} else {
			productRequirementBean.setLastEditorId(getLoginUserId());
			PRODUCT_DEFINE_SERVICE.modifyProductRequirement(productRequirementBean);
		}

		return productRequirementBean;

	}

	/**
	 * 查询下拉列表显示的产品特征
	 */
	@RequestMapping("/getProductFeatureTreeSelect")
	@ResponseBody
	public TreeViewNodeBean[] getProductFeatureTreeSelect(@RequestParam long productVersionId,
			HttpServletRequest request, Model model) throws Exception {

		TreeViewNodeBean[] productFeatureBeans = getSubProductFeature(0, productVersionId, null);

		return productFeatureBeans;
	}

	protected TreeViewNodeBean[] getSubProductFeature(long parentFeatureId, long productVersionId,
			TreeViewNodeBean parentNodeBean) throws Exception {

		ProductFeatureBean[] featureBeans = PRODUCT_DEFINE_SERVICE.getProductFeatureByParentId(productVersionId,
				parentFeatureId);

		List<TreeViewNodeBean> childNodes = new ArrayList<>();

		for (int i = 0; i < featureBeans.length; i++) {

			ProductFeatureBean featureBean = featureBeans[i];

			TreeViewNodeBean nodeBean = new TreeViewNodeBean();

			nodeBean.setNodeData(featureBean);

			nodeBean.setId(String.valueOf(featureBean.getId()));

			nodeBean.setText(featureBean.getFeatureName());

			childNodes.add(nodeBean);

			getSubProductFeature(featureBean.getId(), productVersionId, nodeBean);
		}

		if (parentNodeBean != null) {
			parentNodeBean.setNodes(childNodes.toArray(new TreeViewNodeBean[childNodes.size()]));
		}

		return childNodes.toArray(new TreeViewNodeBean[childNodes.size()]);

	}

	@RequestMapping("/getProductRoleDefineById")
	@ResponseBody
	public ProductRoleDefineBean getProductRoleDefineById(@RequestParam long id) throws Exception {

		return PRODUCT_DEFINE_SERVICE.getProductRoleDefineById(id);
	}

	@RequestMapping("/saveProductRoleDefine")
	@ResponseBody
	public ProductRoleDefineBean saveProductRoleDefine(@ModelAttribute ProductRoleDefineBean productRoleDefineBean)
			throws Exception {

		if (productRoleDefineBean.getId() == 0) {
			PRODUCT_DEFINE_SERVICE.addNewProductRoleDefine(productRoleDefineBean);
		} else {
			PRODUCT_DEFINE_SERVICE.modifyProductRoleDefine(productRoleDefineBean);
		}

		return productRoleDefineBean;

	}

	@RequestMapping("/deleteProductRoleDefines")
	@ResponseBody
	public OperationResult deleteProductRoleDefines(@RequestParam(value = "ids") long[] ids) throws Exception {

		PRODUCT_DEFINE_SERVICE.deleteProductRoleDefines(ids);

		return OperationResult.SUCCESS_RESULT;

	}

	@RequestMapping("/queryProductRoleDefineList")
	@ResponseBody
	public GridBean queryProductRoleDefineList(@ModelAttribute ProductRoleDefineSearchModel searchModel,
			HttpServletRequest request, Model model) throws Exception {

		AbstractSearchHelper<ProductRoleDefineDAOQueryBean, ProductRoleDefineSearchModel> searchHelper = new AbstractSearchHelper<ProductRoleDefineDAOQueryBean, ProductRoleDefineSearchModel>(
				searchModel) {

			@Override
			protected int queryCount(ProductRoleDefineDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductRoleDefineCount(queryBean);
			}

			@Override
			protected Object[] queryData(ProductRoleDefineDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductRoleDefines(queryBean);
			}

			@Override
			protected ProductRoleDefineDAOQueryBean createQueryBean() {
				return new ProductRoleDefineDAOQueryBean();
			}

		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/getProductTeamById")
	@ResponseBody
	public ProductTeamBean getProductTeamById(@RequestParam long id) throws Exception {

		return PRODUCT_DEFINE_SERVICE.getProductTeamStafferById(id);
	}

	@RequestMapping("/saveProductTeam")
	@ResponseBody
	public ProductTeamBean saveProductTeam(@ModelAttribute ProductTeamBean productTeamBean) throws Exception {

		if (productTeamBean.getId() == 0) {
			PRODUCT_DEFINE_SERVICE.addNewProductTeamStaffer(productTeamBean);
		} else {
			PRODUCT_DEFINE_SERVICE.modifyProductTeamStaffer(productTeamBean);
		}

		return productTeamBean;

	}

	@RequestMapping("/batchAddProductTeams")
	@ResponseBody
	public ProductTeamBean[] batchAddProductTeams(@RequestParam long productDefineId,
			@RequestParam(value = "stafferId") long[] stafferIds, @RequestParam String stafferRole,
			@RequestParam(required = false) String remarks) throws Exception {

		ProductTeamBean[] teamBeans = new ProductTeamBean[stafferIds.length];

		for (int i = 0; i < teamBeans.length; i++) {
			teamBeans[i] = new ProductTeamBean();
			teamBeans[i].setProductDefineId(productDefineId);
			teamBeans[i].setStafferId(stafferIds[i]);
			teamBeans[i].setStafferRole(stafferRole);
			teamBeans[i].setRemarks(remarks);
			PRODUCT_DEFINE_SERVICE.addNewProductTeamStaffer(teamBeans[i]);
		}

		return teamBeans;

	}

	@RequestMapping("/deleteProductTeams")
	@ResponseBody
	public OperationResult deleteProductTeams(@RequestParam(value = "ids") long[] ids) throws Exception {

		PRODUCT_DEFINE_SERVICE.deleteProductTeamStaffers(ids);

		return OperationResult.SUCCESS_RESULT;

	}

	@RequestMapping("/queryProductTeamList")
	@ResponseBody
	public GridBean queryProductTeamList(@ModelAttribute ProductTeamSearchModel searchModel, HttpServletRequest request,
			Model model) throws Exception {

		AbstractSearchHelper<ProductTeamDAOQueryBean, ProductTeamSearchModel> searchHelper = new AbstractSearchHelper<ProductTeamDAOQueryBean, ProductTeamSearchModel>(
				searchModel) {

			@Override
			protected int queryCount(ProductTeamDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductTeamStafferCount(queryBean);
			}

			@Override
			protected Object[] queryData(ProductTeamDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductTeamStaffers(queryBean);
			}

			@Override
			protected ProductTeamDAOQueryBean createQueryBean() {
				return new ProductTeamDAOQueryBean();
			}

		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/queryProductRoleRelateList")
	@ResponseBody
	public GridBean queryProductRoleRelateList(@ModelAttribute ProductRoleRelateSearchModel searchModel,
			HttpServletRequest request, Model model) throws Exception {

		AbstractSearchHelper<ProductRoleRelateDAOQueryBean, ProductRoleRelateSearchModel> searchHelper = new AbstractSearchHelper<ProductRoleRelateDAOQueryBean, ProductRoleRelateSearchModel>(
				searchModel) {

			@Override
			protected int queryCount(ProductRoleRelateDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductRoleRelateCount(queryBean);
			}

			@Override
			protected Object[] queryData(ProductRoleRelateDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductRoleRelates(queryBean);
			}

			@Override
			protected ProductRoleRelateDAOQueryBean createQueryBean() {
				return new ProductRoleRelateDAOQueryBean();
			}

		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/getProductRoleDefineList")
	@ResponseBody
	public ProductRoleDefineBean[] getProductRoleDefineList(@RequestParam long productDefineId) throws Exception {
		ProductRoleDefineDAOQueryBean queryBean = new ProductRoleDefineDAOQueryBean();

		queryBean.createCriteria().andProductDefineIdEqualTo(productDefineId);

		return PRODUCT_DEFINE_SERVICE.queryProductRoleDefines(queryBean);
	}

	@RequestMapping("/getProductElementNoRoleRelateList")
	@ResponseBody
	public ProductRoleDefineBean[] getProductElementNoRoleRelateList(@RequestParam long productDefineId,
			@RequestParam long productElementId, @RequestParam String productElementType) throws Exception {
		ProductRoleDefineDAOQueryBean queryBean = new ProductRoleDefineDAOQueryBean();

		ProductRoleRelateDAOQueryBean roleRelateQueryBean = new ProductRoleRelateDAOQueryBean();

		roleRelateQueryBean.addProductRoleDefineIdSelectProperty();

		roleRelateQueryBean.createCriteria().andProductElementIdEqualTo(productElementId)
				.andProductElementTypeEqualTo(productElementType);

		queryBean.createCriteria().andProductDefineIdEqualTo(productDefineId).andIdNotIn(roleRelateQueryBean,
				ProductRoleRelateDAOFactory.getProductRoleRelateDAO());

		return PRODUCT_DEFINE_SERVICE.queryProductRoleDefines(queryBean);
	}

	@RequestMapping("/saveProductRoleRelate")
	@ResponseBody
	public ProductRoleRelateBean saveProductRoleRelate(@ModelAttribute ProductRoleRelateBean roleRelateBean)
			throws Exception {

		if (roleRelateBean.getId() == 0) {
			PRODUCT_DEFINE_SERVICE.addNewProductRoleRelate(roleRelateBean);
		} else {
			PRODUCT_DEFINE_SERVICE.modifyProductRoleRelate(roleRelateBean);
		}

		return roleRelateBean;
	}

	@RequestMapping("/getProductRoleRelateById")
	@ResponseBody
	public ProductRoleRelateBean getProductRoleRelateById(@RequestParam long id) throws Exception {

		return PRODUCT_DEFINE_SERVICE.getProductRoleRelateById(id);
	}

	@RequestMapping("/deleteProductRoleRelates")
	@ResponseBody
	public OperationResult deleteProductRoleRelates(@RequestParam(value = "ids") long[] ids) throws Exception {

		PRODUCT_DEFINE_SERVICE.deleteProductRoleRelates(ids);

		return OperationResult.SUCCESS_RESULT;

	}

	/**
	 * 查询下拉列表显示的产品需求面
	 */
	@RequestMapping("/getProductRequirementFacedTreeSelect")
	@ResponseBody
	public TreeViewNodeBean[] getProductRequirementFacedTreeSelect(@RequestParam long productVersionId,
			HttpServletRequest request, Model model) throws Exception {

		TreeViewNodeBean[] productRequirementBeans = getSubProductRequirement(0, productVersionId, "REQ_FACED", null);

		return productRequirementBeans;
	}

	protected TreeViewNodeBean[] getSubProductRequirement(long parentRequirementId, long productVersionId,
			String requirementType, TreeViewNodeBean parentNodeBean) throws Exception {

		ProductRequirementDAOQueryBean queryBean = new ProductRequirementDAOQueryBean();

		queryBean.setSortProperty(IProductRequirementDAO.SortIndex);

		ProductRequirementDAOQueryBean.Criteria criteria = queryBean.createCriteria();

		criteria.andParentIdEqualTo(parentRequirementId).andRequestTypeEqualTo(requirementType);

		ProductVersionRelateDAOQueryBean versionRelateQueryBean = new ProductVersionRelateDAOQueryBean();

		versionRelateQueryBean.addProductElementIdSelectProperty();

		versionRelateQueryBean.createCriteria().andProductVersionIdEqualTo(productVersionId)
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_REQUIREMENT.getName());

		criteria.andIdIn(versionRelateQueryBean, ProductVersionRelateDAOFactory.getProductVersionRelateDAO());

		ProductRequirementBean[] requirementBeans = PRODUCT_DEFINE_SERVICE.queryProductRequirements(queryBean);

		List<TreeViewNodeBean> childNodes = new ArrayList<TreeViewNodeBean>();

		for (int i = 0; i < requirementBeans.length; i++) {

			ProductRequirementBean requirementBean = requirementBeans[i];

			TreeViewNodeBean nodeBean = new TreeViewNodeBean();

			nodeBean.setNodeData(requirementBean);

			nodeBean.setId(String.valueOf(requirementBean.getId()));

			nodeBean.setText(requirementBean.getRequestName());

			childNodes.add(nodeBean);

			getSubProductRequirement(requirementBean.getId(), productVersionId, requirementType, nodeBean);
		}

		if (parentNodeBean != null) {
			parentNodeBean.setNodes(childNodes.toArray(new TreeViewNodeBean[childNodes.size()]));
		}

		return childNodes.toArray(new TreeViewNodeBean[childNodes.size()]);

	}

	/**
	 * 设置产品需求排序
	 */
	@RequestMapping("/setProductRequirementSort")
	@ResponseBody
	public OperationResult setProductRequirementSort(@RequestParam long productVersionId,
			@RequestParam long productRequirementId, @RequestParam int sortIndex, HttpServletRequest request,
			Model model) throws Exception {

		PRODUCT_DEFINE_SERVICE.setProductRequirementSort(productVersionId, productRequirementId, sortIndex,
				getLoginUserId());

		return OperationResult.SUCCESS_RESULT;
	}

	@RequestMapping("/deleteProductRequirement")
	@ResponseBody
	public OperationResult deleteProductRequirement(@RequestParam long id) throws Exception {

		PRODUCT_DEFINE_SERVICE.deleteProductRequirements(new long[] { id });

		return OperationResult.SUCCESS_RESULT;

	}

	/**
	 * 设置产品特征排序
	 */
	@RequestMapping("/setProductFeatureSort")
	@ResponseBody
	public OperationResult setProductFeatureSort(@RequestParam long productVersionId,
			@RequestParam long productFeatureId, @RequestParam int sortIndex, HttpServletRequest request, Model model)
			throws Exception {

		PRODUCT_DEFINE_SERVICE.setProductFeatureSort(productVersionId, productFeatureId, sortIndex, getLoginUserId());

		return OperationResult.SUCCESS_RESULT;
	}

	@RequestMapping("/saveProductFeatureCheckList")
	@ResponseBody
	public OperationResult saveProductFeatureCheckList(@ModelAttribute ProductFeatureCheckListBean featureCheckListBean)
			throws Exception {

		if (featureCheckListBean.getId() == 0) {
			PRODUCT_DEFINE_SERVICE.addNewProductFeatureCheckList(featureCheckListBean);
		} else {
			PRODUCT_DEFINE_SERVICE.moodifyProductFeatureCheckList(featureCheckListBean);
		}

		OperationResult operationResult = new OperationResult(false, "", featureCheckListBean);

		return operationResult;

	}

	@RequestMapping("/getProductFeatureCheckListById")
	@ResponseBody
	public ProductFeatureCheckListBean getProductFeatureCheckListById(@RequestParam long id) throws Exception {

		return PRODUCT_DEFINE_SERVICE.getProductFeatureCheckListById(id);

	}

	@RequestMapping("/deleteProductFeatureCheckList")
	@ResponseBody
	public OperationResult deleteProductFeatureCheckList(@RequestParam(value = "ids") long[] ids) throws Exception {

		PRODUCT_DEFINE_SERVICE.deleteProductFeatureCheckList(ids);

		return OperationResult.SUCCESS_RESULT;

	}

	@RequestMapping("/setProductFeatureCheckListSort")
	@ResponseBody
	public OperationResult setProductFeatureCheckListSort(@RequestParam long productFeatureId,
			@RequestParam long productFeatureCheckListId, @RequestParam int sortIndex, HttpServletRequest request,
			Model model) throws Exception {

		PRODUCT_DEFINE_SERVICE.setProductFeatureCheckListSort(productFeatureId, productFeatureCheckListId, sortIndex,
				getLoginUserId());

		return OperationResult.SUCCESS_RESULT;
	}

	@RequestMapping("/queryProductRequirementRelateList")
	@ResponseBody
	public GridBean queryProductRequirementRelateList(
			@ModelAttribute ProductRequirementFeatureRelateSearchModel searchModel, HttpServletRequest request,
			Model model) throws Exception {

		AbstractSearchHelper<ProductRequirementFeatureRelateDAOQueryBean, ProductRequirementFeatureRelateSearchModel> searchHelper = new AbstractSearchHelper<ProductRequirementFeatureRelateDAOQueryBean, ProductRequirementFeatureRelateSearchModel>(
				searchModel) {

			@Override
			protected int queryCount(ProductRequirementFeatureRelateDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductRequirementFeatureRelateCount(queryBean);
			}

			@Override
			protected Object[] queryData(ProductRequirementFeatureRelateDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductRequirementFeatureRelates(queryBean);
			}

			@Override
			protected ProductRequirementFeatureRelateDAOQueryBean createQueryBean() {
				return new ProductRequirementFeatureRelateDAOQueryBean();
			}

		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/addProductRequirementFeatureRelates")
	@ResponseBody
	public ProductRequirementFeatureRelateBean addProductRequirementFeatureRelates(@RequestParam long productFeatureId,
			@RequestParam long productFeatureVersionId, @RequestParam long productRequirementId,
			@RequestParam long productRequirementVersionId) throws Exception {

		ProductRequirementFeatureRelateBean relateBean = new ProductRequirementFeatureRelateBean();

		relateBean.setProductFeatureId(productFeatureId);
		relateBean.setProductFeatureVersionId(productFeatureVersionId);
		relateBean.setProductRequirementId(productRequirementId);
		relateBean.setProductRequirementVersionId(productRequirementVersionId);

		PRODUCT_DEFINE_SERVICE
				.addProductRequirementFeatureRelate(new ProductRequirementFeatureRelateBean[] { relateBean });

		return relateBean;
	}

	@RequestMapping("/deleteProductRequirementFeatureRelates")
	@ResponseBody
	public OperationResult deleteProductRequirementFeatureRelates(@RequestParam(value = "ids") long[] ids)
			throws Exception {

		PRODUCT_DEFINE_SERVICE.removeProductRequirementFeatureRelates(ids);

		return OperationResult.SUCCESS_RESULT;

	}

	@RequestMapping("/addNewProductFeatureByRequirement")
	@ResponseBody
	public ProductFeatureBean addNewProductFeatureByRequirement(@RequestParam long productRequirementVersionId,
			@RequestParam long productRequirementId, @RequestParam long productFeatureVersionId,
			@ModelAttribute ProductFeatureBean productFeatureBean) throws Exception {

		PRODUCT_DEFINE_SERVICE.addNewProductFeature(productFeatureVersionId, productFeatureBean);

		ProductRoleRelateDAOQueryBean queryBean = new ProductRoleRelateDAOQueryBean();

		queryBean.createCriteria().andProductElementIdEqualTo(productRequirementId)
				.andProductElementTypeEqualTo("PRODUCT_REQUIREMENT");

		ProductRoleRelateBean[] roleRelateBeans = PRODUCT_DEFINE_SERVICE.queryProductRoleRelates(queryBean);

		for (int i = 0; i < roleRelateBeans.length; i++) {
			ProductRoleRelateBean productRoleRelateBean = new ProductRoleRelateBean();

			productRoleRelateBean.setProductElementId(productFeatureBean.getId());
			productRoleRelateBean.setProductElementType("PRODUCT_FEATURE");
			productRoleRelateBean.setProductRoleDefineId(roleRelateBeans[i].getProductRoleDefineId());

			PRODUCT_DEFINE_SERVICE.addNewProductRoleRelate(productRoleRelateBean);

		}

		ProductRequirementFeatureRelateBean relateBean = new ProductRequirementFeatureRelateBean();

		relateBean.setProductFeatureId(productFeatureBean.getId());
		relateBean.setProductFeatureVersionId(productFeatureVersionId);
		relateBean.setProductRequirementId(productRequirementId);
		relateBean.setProductRequirementVersionId(productRequirementVersionId);

		PRODUCT_DEFINE_SERVICE
				.addProductRequirementFeatureRelate(new ProductRequirementFeatureRelateBean[] { relateBean });

		return productFeatureBean;
	}

	@RequestMapping("/queryProductGlossaryRelateList")
	@ResponseBody
	public GridBean queryProductGlossaryRelateList(@ModelAttribute ProductGlossaryRelateSearchModel searchModel,
			HttpServletRequest request, Model model) throws Exception {

		AbstractSearchHelper<ProductGlossaryRelateDAOQueryBean, ProductGlossaryRelateSearchModel> searchHelper = new AbstractSearchHelper<ProductGlossaryRelateDAOQueryBean, ProductGlossaryRelateSearchModel>(
				searchModel) {

			@Override
			protected int queryCount(ProductGlossaryRelateDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductGlossaryRelateCount(queryBean);
			}

			@Override
			protected Object[] queryData(ProductGlossaryRelateDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductGlossaryRelates(queryBean);
			}

			@Override
			protected ProductGlossaryRelateDAOQueryBean createQueryBean() {
				return new ProductGlossaryRelateDAOQueryBean();
			}

		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/getProductGlossaryList")
	@ResponseBody
	public ProductGlossaryBean[] getProductGlossaryList(@RequestParam long productVersionId, @RequestParam String type)
			throws Exception {

		ProductGlossaryDAOQueryBean queryBean = new ProductGlossaryDAOQueryBean();

		ProductVersionRelateDAOQueryBean versionRelateQueryBean = new ProductVersionRelateDAOQueryBean();

		versionRelateQueryBean.addProductElementIdSelectProperty();

		versionRelateQueryBean.createCriteria().andProductVersionIdEqualTo(productVersionId)
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_GLOSSARY.getName());

		queryBean.createCriteria()
				.andIdIn(versionRelateQueryBean, ProductVersionRelateDAOFactory.getProductVersionRelateDAO())
				.andTypeEqualTo(type);

		return PRODUCT_DEFINE_SERVICE.queryProductGlossary(queryBean);
	}

	@RequestMapping("/saveProductGlossaryRelate")
	@ResponseBody
	public ProductGlossaryRelateBean saveProductGlossaryRelate(
			@ModelAttribute ProductGlossaryRelateBean glossaryRelateBean, HttpServletRequest request, Model model)
			throws Exception {

		if (glossaryRelateBean.getId() != 0) {
			PRODUCT_DEFINE_SERVICE.modifyProductGlossaryRelate(glossaryRelateBean);
		} else {
			PRODUCT_DEFINE_SERVICE.addNewProductGlossaryRelate(glossaryRelateBean);
		}

		return glossaryRelateBean;
	}

	@RequestMapping("/deleteProductGlossaryRelates")
	@ResponseBody
	public OperationResult deleteProductGlossaryRelates(@RequestParam(value = "ids") long[] ids) throws Exception {

		PRODUCT_DEFINE_SERVICE.deleteProductGlossaryRelates(ids);

		return OperationResult.SUCCESS_RESULT;
	}

	@RequestMapping("/getProductGlossaryRelateById")
	@ResponseBody
	public ProductGlossaryRelateBean getProductGlossaryRelateById(@RequestParam long id) throws Exception {

		return PRODUCT_DEFINE_SERVICE.getProductGlossaryRelateById(id);
	}

	@RequestMapping("/queryProductGlossaryAttrList")
	@ResponseBody
	public GridBean queryProductGlossaryAttrList(@ModelAttribute ProductGlossaryAttrSearchModel searchModel,
			HttpServletRequest request, Model model) throws Exception {

		AbstractSearchHelper<ProductGlossaryAttrDAOQueryBean, ProductGlossaryAttrSearchModel> searchHelper = new AbstractSearchHelper<ProductGlossaryAttrDAOQueryBean, ProductGlossaryAttrSearchModel>(
				searchModel) {

			@Override
			protected int queryCount(ProductGlossaryAttrDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductGlossaryAttrCount(queryBean);
			}

			@Override
			protected Object[] queryData(ProductGlossaryAttrDAOQueryBean queryBean) throws Exception {
				return PRODUCT_DEFINE_SERVICE.queryProductGlossaryAttrs(queryBean);
			}

			@Override
			protected ProductGlossaryAttrDAOQueryBean createQueryBean() {
				return new ProductGlossaryAttrDAOQueryBean();
			}

		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/saveProductGlossaryAttr")
	@ResponseBody
	public ProductGlossaryAttrBean saveProductGlossaryAttr(@ModelAttribute ProductGlossaryAttrBean glossaryAttrBean,
			HttpServletRequest request, Model model) throws Exception {

		if (glossaryAttrBean.getId() != 0) {
			PRODUCT_DEFINE_SERVICE.modifyProductGlossaryAttr(glossaryAttrBean);
		} else {
			PRODUCT_DEFINE_SERVICE.addNewProductGlossaryAttr(glossaryAttrBean);
		}

		return glossaryAttrBean;
	}

	@RequestMapping("/deleteProductGlossaryAttrs")
	@ResponseBody
	public OperationResult deleteProductGlossaryAttrs(@RequestParam(value = "ids") long[] ids) throws Exception {

		PRODUCT_DEFINE_SERVICE.deleteProductGlossaryAttrs(ids);

		return OperationResult.SUCCESS_RESULT;
	}

	@RequestMapping("/getProductGlossaryAttrById")
	@ResponseBody
	public ProductGlossaryAttrBean getProductGlossaryAttrById(@RequestParam long id) throws Exception {

		return PRODUCT_DEFINE_SERVICE.getProductGlossaryAttrById(id);
	}

	@RequestMapping("/getProductRequirementCoverageRate")
	@ResponseBody
	public String getProductRequirementCoverageRate(@RequestParam long productRequirementId,
			@RequestParam long productVersionId) throws Exception {

		ProductRequirementBean requirementBean = PRODUCT_DEFINE_SERVICE.getProductRequirementById(productRequirementId);

		if (requirementBean.getRequestType().equals("REQ_FACED")) {

			ProductRequirementDAOQueryBean qeryBean = new ProductRequirementDAOQueryBean();

			qeryBean.setSortProperty(IProductRequirementDAO.SortIndex);

			ProductRequirementDAOQueryBean.Criteria criteria = qeryBean.createCriteria();

			criteria.andParentIdEqualTo(productRequirementId);

			if (productVersionId != 0) {
				ProductVersionRelateDAOQueryBean versionRelateQueryBean = new ProductVersionRelateDAOQueryBean();

				versionRelateQueryBean.addProductElementIdSelectProperty();

				versionRelateQueryBean.createCriteria().andProductVersionIdEqualTo(productVersionId)
						.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_REQUIREMENT.getName());

				criteria.andIdIn(versionRelateQueryBean, ProductVersionRelateDAOFactory.getProductVersionRelateDAO());
			}

			ProductRequirementBean[] requirementBeans = PRODUCT_DEFINE_SERVICE.queryProductRequirements(qeryBean);

			long[] requirementIds = new long[requirementBeans.length];

			for (int i = 0; i < requirementIds.length; i++) {
				requirementIds[i] = requirementBeans[i].getId();
			}

			ProductRequirementFeatureRelateDAOQueryBean queryBean = new ProductRequirementFeatureRelateDAOQueryBean();

			queryBean.createCriteria().andProductRequirementVersionIdEqualTo(productVersionId)
					.andProductRequirementIdIn(requirementIds);

			int count = PRODUCT_DEFINE_SERVICE.queryProductRequirementFeatureRelateCount(queryBean);

			if (count > requirementIds.length) {
				return "功能覆盖率: 100%";
			} else {
				return "功能覆盖率: " + accuracy(count, requirementIds.length, 1);
			}

		} else {
			ProductRequirementFeatureRelateDAOQueryBean queryBean = new ProductRequirementFeatureRelateDAOQueryBean();

			queryBean.createCriteria().andProductRequirementVersionIdEqualTo(productVersionId)
					.andProductRequirementIdEqualTo(productRequirementId);

			int count = PRODUCT_DEFINE_SERVICE.queryProductRequirementFeatureRelateCount(queryBean);

			return "已对应" + count + "个产品功能";
		}

	}

	private static String accuracy(double num, double total, int scale) {
		DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
		// 可以设置精确几位小数
		df.setMaximumFractionDigits(scale);
		// 模式 例如四舍五入
		df.setRoundingMode(RoundingMode.HALF_UP);
		double accuracy_num = num / total * 100;
		return df.format(accuracy_num) + "%";
	}

}
